/**************************************************************************
*  Black Knight - Chess Engine                                            *
*  Copyright (C) 2009  Victor Rusu                                        *
*                                                                         *
*  This program is free software: you can redistribute it and/or modify   *
*  it under the terms of the GNU General Public License as published by   *
*  the Free Software Foundation, either version 3 of the License, or      *
*  (at your option) any later version.                                    *
*                                                                         *
*  This program is distributed in the hope that it will be useful,        *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of         *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the           *
*  GNU General Public License for more details.                           *
*                                                                         *
*  You should have received a copy of the GNU General Public License      *
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.  *
**************************************************************************/

#ifndef LOGIC_POSITION_H_
#define LOGIC_POSITION_H_

#include <vector>
#include <string>

class Position {
public:
    static const int kSides = 2;
    static const int kPieceTypes = 6;
    static const int kBoardSize = 8;

    enum side {
        white,
        black
    };

    enum piece {
        king,
        queen,
        rook,
        knight,
        bishop,
        pawn
    };

private:
    static const std::string kStartPosition;

    bool board_[kSides][kPieceTypes][kBoardSize][kBoardSize];
    bool castle_[kSides][2];
    bool attacked_[kSides][kBoardSize][kBoardSize];

    side side_to_move_;

    int moves_since_capture_;
    int move_number_;

    std::string en_passant_;

public:

    explicit Position(std::string = kStartPosition);
    Position(const Position&);
    ~Position();
    Position& operator=(const Position&);

    void get_coordinates(char, char, int&, int&);
    std::string give_coordinates(int, int);

    bool is_on_board(int, int);
    bool is_piece(side, int, int);

    side to_move();
    bool is_valid_move(std::string);
    bool can_move_to(int, int);
    void compute_attacked();
    bool is_attacked(side, int, int);

    bool is_checked(side);
    bool is_checked_mate();
    bool is_stale_mate();

    std::vector<std::string> get_piece_moves(side, piece, int, int);
    std::vector<std::string> get_all_moves(side);
    std::vector<std::string> get_valid_moves(side);

    void move(std::string);
};

#endif // LOGIC_POSITION_H_
